package org.hscoder.mongo.sync;

import com.mongodb.client.MongoClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class PoolBeanMonitor implements Runnable {

    private static Logger logger = LoggerFactory.getLogger(PoolBeanMonitor.class);
    private MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

    private ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);

    /**
     * 开启监听
     */
    public void start() {
        logger.info("start monitoring for connection pool.");

        //每5秒钟打印一次
        scheduledThreadPool.scheduleAtFixedRate(this, 5, 5, TimeUnit.SECONDS);
    }

    /**
     * 停止监听
     */
    public void stop() {
        this.scheduledThreadPool.shutdownNow();
        logger.info("stop monitoring for connection pool.");
    }

    @Override
    public void run() {
        try {
            Set<ObjectInstance> instances = mbeanServer.queryMBeans(new ObjectName("org.mongodb.driver:type=ConnectionPool,*"), null);
            for (ObjectInstance instance : instances) {
                String className = instance.getClassName();
                if (!className.contains("mongo")) {
                    continue;
                }

                //获得MBean对象
                ObjectName objectName = instance.getObjectName();

                //抓取属性
                String[] attrs = new String[]{"CheckedOutCount", "Host", "Port",
                        "MinSize", "MaxSize", "Size", "WaitQueueSize"};

                StringBuilder sb = new StringBuilder();
                for (String attr : attrs) {
                    sb.append(attr).append("=").append(mbeanServer.getAttribute(objectName, attr)).append("|");
                }

                logger.info("ConnPoolStatistic - {}: \n\t - {}", objectName, sb.toString());
            }
        } catch (Throwable e) {
            logger.error("error occurs", e);
        }

    }

    public static void main(String[] args) throws InterruptedException {

        MongoClient client = MongoClientFactory.build();

        PoolBeanMonitor monitor = new PoolBeanMonitor();
        monitor.start();

        DocumentOperation.find(client);
        Thread.sleep(20000);

        monitor.stop();
        client.close();
    }

}
